﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Text.RegularExpressions;
using App_Code.Helpers;
using Rss;

namespace App_Code.SiteParsers
{
    /// <summary>
    /// Summary description for CuevanaTV
    /// </summary>
    public class CuevanaTV : BasePluginParser
    {
        private const string DEFAULT_URL = "http://www.cuevana.tv/";
        private const string MOVIES_URL = "peliculas";
        private const string SERIES_URL = "series";

        public CuevanaTV()
        {
            this._defaultUrl = DEFAULT_URL;

            this.Name = "cuevana.tv";
            this.Description = "אתר צפייה ישירה";
            this.Url = DEFAULT_URL;
        }

        #region Implementation of IPluginParser
        public override RssFeed Run(NameValueCollection queryStringParams)
        {
            this.InitMembers(queryStringParams);

            switch (this._pluginMode)
            {
                case PluginMode.IDLE_MODE:
                    return LoadMainCategories();

                case PluginMode.CATEGORIES_MODE:
                    return LoadCategories();

                case PluginMode.MOVIES_MODE:
                    return LoadMovies();

                case PluginMode.NEXT_PAGE_MODE:
                    return LoadMovies();

                case PluginMode.MOVIE_MODE:
                    return this.LoadMovie();

                default:
                    throw new Exception("Unknown mode");
            }
        }

        public override void RunUntillPage(int pageNumber)
        {
            //for (var i = 1; i <= pageNumber; i++)
            //{
            //    this.Url = string.Format("{0}page/{1}", DEFAULT_URL, i);
            //    this.LoadMovies();
            //}
        }

        #endregion

        #region Private Methods
        private RssFeed LoadMainCategories()
        {
            try
            {
                var feed = LoadFromCache(this.Url);
                if (feed != null) return feed;

                var rssChannel = new RssChannel
                {
                    Title = string.Format("Movies Channel - {0}", DateTime.Now),
                    Description = "Categories List",
                    Link = new Uri(string.Format("{0}?pluginId={1}", Utils.GetSiteUrl(), this._pluginId)),
                    Language = "he"
                };

                rssChannel.LastBuildDate = rssChannel.Items.LatestPubDate();

                var movie = new Movie
                {
                    Name = "Movies",
                };

                movie.MovieLinks.Add(WrapUrl(MOVIES_URL));

                var movieItems = movie.GetRssItems(Utils.GetSiteUrl(), this._pluginId, (int)PluginMode.CATEGORIES_MODE);
                foreach (var movieItem in movieItems)
                {
                    rssChannel.Items.Add(movieItem);
                }

                movie = new Movie
                {
                    Name = "Series",
                };

                movie.MovieLinks.Add(WrapUrl(SERIES_URL));

                movieItems = movie.GetRssItems(Utils.GetSiteUrl(), this._pluginId, (int)PluginMode.MOVIES_MODE);
                foreach (var movieItem in movieItems)
                {
                    rssChannel.Items.Add(movieItem);
                }

                feed = new RssFeed { Encoding = Encoding.UTF8 };
                feed.Channels.Add(rssChannel);

                this.AddToCache(this.Url, feed);

                return feed;
            }
            catch (Exception ex)
            {
                return CreateErrorResponse(ex.Message);
            }
        }

        private RssFeed LoadCategories()
        {
            try
            {
                var feed = LoadFromCache(this.Url);
                if (feed != null) return feed;

                var page = Utils.GetPage(this.Url, Encoding.UTF8);

                var rssChannel = new RssChannel
                {
                    Title = string.Format("Movies Channel - {0}", DateTime.Now),
                    Description = "Categories List",
                    Link = new Uri(string.Format("{0}?pluginId={1}", Utils.GetSiteUrl(), this._pluginId)),
                    Language = "he"
                };

                rssChannel.LastBuildDate = rssChannel.Items.LatestPubDate();

                var sectioMatch = Regex.Match(page, "<div id=\"submenu\">(.+?)</div>", RegexOptions.Singleline);
                if (!sectioMatch.Success)
                    throw new Exception("Failed Parse Movies categories section");

                var categoriesSection = sectioMatch.Groups[1].Value;

                const string moviesContainerExpression = "<li><a href=\"(.+?)\".*?<span.*?>(.+?)<";
                var matches = Regex.Matches(categoriesSection, moviesContainerExpression, RegexOptions.Singleline);
                foreach (Match match in matches)
                {
                    var pageLink = WrapUrl(match.Groups[1].Value);
                    var title = match.Groups[2].Value;

                    var movie = new Movie
                    {
                        Name = title,
                    };

                    movie.MovieLinks.Add(pageLink);

                    var movieItems = movie.GetRssItems(Utils.GetSiteUrl(), this._pluginId, (int)PluginMode.MOVIES_MODE);
                    foreach (var movieItem in movieItems)
                    {
                        rssChannel.Items.Add(movieItem);
                    }
                }

                feed = new RssFeed { Encoding = Encoding.UTF8 };
                feed.Channels.Add(rssChannel);

                this.AddToCache(this.Url, feed);

                return feed;
            }
            catch (Exception ex)
            {
                return CreateErrorResponse(ex.Message);
            }
        }

        private RssFeed LoadMovies()
        {
            try
            {
                var feed = LoadFromCache(this.Url);
                if (feed != null) return feed;

                var page = Utils.GetPage(this.Url, Encoding.UTF8);

                var rssChannel = new RssChannel
                {
                    Title = "Movies Channel",
                    Description = "Movies List",
                    Link = new Uri(string.Format("{0}?pluginId={1}", Utils.GetSiteUrl(), this._pluginId)),
                    Language = "he"
                };

                rssChannel.LastBuildDate = rssChannel.Items.LatestPubDate();

                var videosRegEx = "<tr class='row[^<]+";
                videosRegEx += "<td valign='top'><a href='([^']+)'><img src='([^']+)'[^>]+></a></td>[^<]+";
                videosRegEx += "<td valign='top'><div class='tit'><a[^>]+>([^<]+)</a></div>[^<]+";
                videosRegEx += "<div class='font11'>([^<]+)<";

                var matches = Regex.Matches(page, videosRegEx, RegexOptions.Singleline);
                foreach (Match match in matches)
                {
                    var moviePageLink = WrapUrl(match.Groups[1].Value);
                    var imageLink = match.Groups[2].Value;
                    var movieTitle = match.Groups[3].Value;
                    var plot = match.Groups[4].Value;

                    var movie = new Movie
                                    {
                                        Name = movieTitle,
                                        ImageLink = imageLink,
                                        Plot = plot,
                                        MovieLinks = new List<string> {moviePageLink}
                                    };

                    var movieItems = movie.GetRssItems(Utils.GetSiteUrl(), this._pluginId, (int)PluginMode.MOVIE_MODE);
                    foreach (var movieItem in movieItems)
                    {
                        rssChannel.Items.Add(movieItem);
                    }
                }

                var nextPageMovie = new Movie
                {
                    Name = "דף הבא",
                };

                nextPageMovie.MovieLinks.Add(GetNextPageLink(page));
                var nextPageItems = nextPageMovie.GetRssItems(Utils.GetSiteUrl(), this._pluginId, (int)PluginMode.NEXT_PAGE_MODE);
                rssChannel.Items.Add(nextPageItems[0]);

                feed = new RssFeed { Encoding = Encoding.UTF8 };
                feed.Channels.Add(rssChannel);

                AddToCache(this.Url, feed);

                return feed;
            }
            catch (Exception ex)
            {
                return CreateErrorResponse(ex.Message);
            }
        }

        private string GetNextPageLink(string pageContent)
        {
            try
            {
                const string nextPageExpression = "<a class='next' href='(.+?)'";
                var match = Regex.Match(pageContent, nextPageExpression, RegexOptions.Singleline);
                if (match.Success)
                {
                    if (this.Url.Contains(MOVIES_URL))
                        return string.Format("{0}{1}/{2}", DEFAULT_URL, MOVIES_URL, match.Groups[1].Value.Trim());
                    return string.Format("{0}{1}/{2}", DEFAULT_URL, SERIES_URL, match.Groups[1].Value.Trim());
                }
            }
            catch { }

            return this.Url;
        }
        
        private string WrapUrl(string url)
        {
            return string.Format("{0}{1}", DEFAULT_URL, url); 
        }
        #endregion
    }
}